package com.mrdeer.web.controller.sys;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mrdeer.common.JSONResult;
import com.mrdeer.common.entity.dto.RedisDTO;
import com.mrdeer.common.entity.sys.RedisInfo;
import com.mrdeer.common.tools.RedisTemplateHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@Api(tags = "Redis缓存管理接口")
@RequestMapping("/mrdeer/redis")
@Transactional
public class SysRedisController {

    /**
     * 最大获取10万个键值
     */
    private static final int maxSize = 100000;

    @Resource
    private RedisTemplateHelper redisTemplate;

    @RequestMapping(value = "/getAllByPage/{page}/{pageSize}", method = RequestMethod.GET)
    @ApiOperation(value = "分页获取全部")
    public JSONResult getAllByPage(@RequestParam(required = false) String key, @PathVariable Integer page, @PathVariable Integer pageSize) {
        List<RedisDTO> list = new ArrayList<>();
        if (StrUtil.isNotBlank(key)) {
            key = "*" + key + "*";
        } else {
            key = "*";
        }
        Set<String> keys = redisTemplate.scan(key);
        int size = keys.size();
        //限制10万个
        if (size > maxSize) {
            size = maxSize;
        }
        int i = 0;
        for (String s : keys) {
            if (i > size) {
                break;
            }
            RedisDTO redisDTO = new RedisDTO(s, "", null);
            list.add(redisDTO);
            i++;
        }
        list.forEach(e -> {
            String value = "";
            try {
                value = redisTemplate.get(e.getKey());
                if (value.length() > 150) {
                    value = value.substring(0, 150) + "...";
                }
            } catch (Exception exception) {
                value = "非字符格式数据";
            }
            e.setValue(value);
            e.setExpireTime(redisTemplate.getExpire(e.getKey(), TimeUnit.SECONDS));
        });
        return JSONResult.ok(list.subList(page, pageSize));
    }

    @RequestMapping(value = "/getByKey/{key}", method = RequestMethod.GET)
    @ApiOperation(value = "通过key获取")
    public JSONResult getByKey(@PathVariable String key) {
        Map<String, Object> map = new HashMap<>();
        String value = redisTemplate.get(key);
        Long expireTime = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        map.put("value", value);
        map.put("expireTime", expireTime);
        return JSONResult.ok(map);
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiOperation(value = "添加或编辑")
    public JSONResult save(@RequestParam String key, @RequestParam String value, @RequestParam Long expireTime) {
        if (expireTime < 0) {
            redisTemplate.set(key, value);
        } else if (expireTime > 0) {
            redisTemplate.set(key, value, expireTime, TimeUnit.SECONDS);
        }
        return JSONResult.ok("保存成功");
    }

    @RequestMapping(value = "/delByKeys", method = RequestMethod.POST)
    @ApiOperation(value = "批量删除")
    public JSONResult delByKeys(@RequestParam String[] keys) {
        for (String key : keys) {
            redisTemplate.delete(key);
        }
        return JSONResult.ok("删除成功");
    }

    @RequestMapping(value = "/delAll", method = RequestMethod.POST)
    @ApiOperation(value = "全部删除")
    public JSONResult delAll() {
        redisTemplate.deleteByPattern("*");
        return JSONResult.ok("删除成功");
    }

    @RequestMapping(value = "/getKeySize", method = RequestMethod.GET)
    @ApiOperation(value = "获取实时key大小")
    public JSONResult getKeySize() {
        Map<String, Object> map = new HashMap<>(16);
        map.put("keySize", redisTemplate.getConnectionFactory().getConnection().dbSize());
        map.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
        return JSONResult.ok(map);
    }

    @RequestMapping(value = "/getMemory", method = RequestMethod.GET)
    @ApiOperation(value = "获取实时内存大小")
    public JSONResult getMemory() {
        Map<String, Object> map = new HashMap<>(16);
        Properties memory = redisTemplate.getConnectionFactory().getConnection().info("memory");
        map.put("memory", memory.get("used_memory"));
        map.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
        return JSONResult.ok(map);
    }

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @ApiOperation(value = "获取Redis信息")
    public JSONResult info() {
        List<RedisInfo> infoList = new ArrayList<>();
        Properties properties = redisTemplate.getConnectionFactory().getConnection().info();
        Set<Object> keys = properties.keySet();
        for (Object key : keys) {
            String value = properties.get(key).toString();
            RedisInfo redisInfo = new RedisInfo();
            redisInfo.setKey(key.toString());
            redisInfo.setValue(value);
            infoList.add(redisInfo);
        }
        return JSONResult.ok(infoList);
    }
}
